#ifndef PWAVE_PWAVEPROBLEM_H
#define PWAVE_PWAVEPROBLEM_H

#include <string>
#include <vector>
#include <cstring>

#include "Miscellaneous_structs.h"
#include "swt_env_win_linux.h"
#include "ProblemCart2DBlk.h"
#include "MPI_TopoCart2D.h"


class PWaveProblem : public ProblemCart2DBlk {
public:
    // global grid info
    int NGP_X, NGP_Y, NGP_Z;

    int PML_XN, PML_XP, PML_YN, PML_YP, PML_ZN, PML_ZP;

    int halo;
    double h;



    // example-specific physical info
    int end_time_steps;
    double realX, realY, realZ;             // the real length of each dimension
    double dt;

    bool use_outer_model;
    std::string model_src;
    double c1, c2;
    int h1, h2;

    int num_src;
    std::vector<GlobalSrcInfo> src_info;    // location of wave src in grid_points

    double B;


    bool output_iter_frames_x, output_iter_frames_y, output_iter_frames_z;
    int target_x, target_y, target_z;
    int frames_freq_x, frames_freq_y, frames_freq_z;

    int num_output_pts;
    std::vector<GlobalSrcInfo> output_pts_info;
    // use GlobalSrcInfo to avoid constructing a new data structure to store coords of output points




    // other info
    char identifier[200];

    bool raw;           // if true, output will be of double type, or the output frames will be in the dtype of short
    bool out_final3D;
    std::string out_prefix;



    //! info that belongs to the local block
    std::vector<LocalSrcInfo> inblk_src_info;           // in-block source info
    std::vector<OutputPtInfo> inblk_output_pt_info;     // in-block outputting point info

    virtual void init(const CmdLineArgs* cmd);
    virtual void partition(Data3D* data3D);
    virtual void create_MPI_topo(MPI_Topo* topo);
    virtual void init_model(Data3D* data3D, const MPI_Topo* topo);
    virtual double* solve(Data3D* data3D, const MPI_Topo* topo);

    virtual void free();

    void write_log(const Data3D* data3D, double init_abs_sec, double compute_abs_sec, double output_abs_sec, double start_abs_sec) const;
};

#endif //PWAVE_PWAVEPROBLEM_H
